package cn.yhp.chatgpt.data.domain.openai.service;

import cn.bugstack.chatglm.session.OpenAiSession;
import cn.yhp.chatgpt.data.domain.openai.model.aggregates.ChatProcessAggregate;
import cn.yhp.chatgpt.data.domain.openai.model.entity.RuleLogicEntity;
import cn.yhp.chatgpt.data.domain.openai.model.valobj.LogicCheckTypeVO;
import cn.yhp.chatgpt.data.domain.openai.service.rule.factory.DefaultLogicFactory;
import cn.yhp.chatgpt.data.types.common.Constants;
import cn.yhp.chatgpt.data.types.exception.ChatGPTException;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import javax.annotation.Resource;

/**
 * 通用功能
 * @author yhp
 * @description
 * @date 2024/2/1
 */
@Slf4j
public abstract class AbstractChatService implements IChatService{

    @Resource
    protected OpenAiSession openAiSession;

    @Override
    public ResponseBodyEmitter completions(ChatProcessAggregate chatProcess,ResponseBodyEmitter emitter) {
        // 成功 or 失败的打印信息
        emitter.onCompletion(()-> log.info("流式应答完成，使用模型：{}",chatProcess.getModel()));
        emitter.onError(e->log.info("流式应答异常，使用模型：{}",chatProcess.getModel(),e));

        try {
            // 规则过滤
            RuleLogicEntity<ChatProcessAggregate> ruleLogicEntity = this.doCheckLogic(chatProcess, DefaultLogicFactory.LogicModel.ACCESS_LIMIT,
                    DefaultLogicFactory.LogicModel.SENSITIVE_WORD);
            // 不成功返回信息
            if (!LogicCheckTypeVO.SUCCESS.equals(ruleLogicEntity.getType())) {
                emitter.send(ruleLogicEntity.getInfo());
                emitter.complete();
                return emitter;
            }
            // 3、应答处理
            this.doMessageResponse(ruleLogicEntity.getData(),emitter);
        } catch (Exception e) {
            log.error("异常：",e);
            throw new ChatGPTException(Constants.ResponseCode.UN_ERROR);
        }
        // 4、结果返回
        return emitter;
    }

    /**
     * 真正去请求openai的接口
     * @param chatProcess
     * @param responseBodyEmitter
     */
    protected abstract void doMessageResponse(ChatProcessAggregate chatProcess, ResponseBodyEmitter responseBodyEmitter) throws JsonProcessingException;

    /**
     * 具体的规则过滤
     * @param chatProcess
     * @param logics
     * @return
     * @throws Exception
     */
    protected abstract RuleLogicEntity<ChatProcessAggregate> doCheckLogic(ChatProcessAggregate chatProcess, DefaultLogicFactory.LogicModel... logics) throws Exception;

}
